package com.cman777.springc.web.holder;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.Validate;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

/**
 * @author chenzhicong
 * @time 2019/11/8 16:30
 * @description 存放ip,request，method，operatorId
 * 线程本地变量是分别在mdcFilter和LogAspect存入的
 */
public class RequestInfoHolder {
    private static final ThreadLocal<Info> THREAD_LOCAL = new ThreadLocal<>();

    @Setter
    @Getter
    private static class Info {

        private String ip;

        private HttpServletRequest request;


        private String body;

        /**
         * post
         * get
         * 这种
         */
        private String method;

        private String uri;

        private String operatorId;

    }

    /**
     * 每个线程，只允许在脚手架里面被调用一次
     */
    public static void init() {
        if (null == THREAD_LOCAL.get()) {
            THREAD_LOCAL.set(new Info());
        }
    }

    /**
     * 每个线程，只允许在脚手架里面被调用一次
     * @param ip
     */
    public static void setIp(String ip) {
        Validate.notBlank(ip);
        RequestInfoHolder.Info info = THREAD_LOCAL.get();
        info.setIp(ip);
        THREAD_LOCAL.set(info);
    }


    /**
     *每个线程，只允许在脚手架里面被调用一次
     * @param request
     */
    public static void setRequest(HttpServletRequest request) {
        Validate.notNull(request);
        Info info = THREAD_LOCAL.get();
        info.setRequest(request);
        THREAD_LOCAL.set(info);
    }

    /**
     *每个线程，只允许在脚手架里面被调用一次
     * @param method
     */
    public static void setMethod(String method) {
        Validate.notBlank(method);
        Info info = THREAD_LOCAL.get();
        info.setMethod(method);
        THREAD_LOCAL.set(info);
    }

    /**
     *每个线程，只允许在脚手架里面被调用一次
     * @param uri
     */
    public static void setUri(String uri) {
        Validate.notBlank(uri);
        Info info = THREAD_LOCAL.get();
        info.setUri(uri);
        THREAD_LOCAL.set(info);
    }

    /**
     * 每个线程，只允许在脚手架里面被调用一次
     * @param operatorId
     */
    public static void setOperatorId(String operatorId) {
        Validate.notBlank(operatorId);
        Info info = THREAD_LOCAL.get();
        info.setOperatorId(operatorId);
        THREAD_LOCAL.set(info);
    }

    /**
     *
     * @return
     */
    public static String getIp() {
        return Optional.ofNullable(THREAD_LOCAL.get())
                .map(Info::getIp).orElse(null);
    }

    /**
     *
     * @return get 或 post（包含delete和put）
     */
    public static String getMethod() {
        return Optional.ofNullable(THREAD_LOCAL.get())
                .map(Info::getMethod).orElse(null);
    }


    /**
     *
     * @return
     */
    public static String getUri() {
        return Optional.ofNullable(THREAD_LOCAL.get())
                .map(Info::getUri).orElse(null);
    }

    /**
     *
     * @return
     */
    public static String getOperatorId() {
        return Optional.ofNullable(THREAD_LOCAL.get())
                .map(Info::getOperatorId).orElse(null);
    }

    /**
     *
     * @return
     */
    public static HttpServletRequest getRequest() {
        return Optional.ofNullable(THREAD_LOCAL.get())
                .map(Info::getRequest).orElse(null);
    }


    public static  void setBody(String body){
        RequestInfoHolder.Info info = THREAD_LOCAL.get();
        info.setBody(body);
        THREAD_LOCAL.set(info);
    }

    public static  String getBody(){
        return Optional.ofNullable(THREAD_LOCAL.get())
                .map(Info::getBody).orElse(null);
    }

    /**
     *
     */
    public static void remove() {
        THREAD_LOCAL.remove();
    }
}
